package Network;

import baseservergrid.ModeCompilation;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.util.Iterator;
import java.util.LinkedList;
import javax.swing.Timer;


/**
 * Организация сервиса пинга с заданным интервалом
 * @author Volk ID = 1001
 */
public class PingService {
  //--------------------Константы класса---------------------------------------
  static final public int DEFAULT_TIME = 1000; //Время по умолчанию

  //--------------------Аттрибуты класса---------------------------------------
  private Timer timer = null; //Таймер по которому будет производится пингование
  private NetworkAddress address = null; //Адресс пингуемого сервера
  private INetworkRetryInterface object = null; //Объект который необходимо пинговать
  private int time = 1000; //Время пингования
  //Список обработчиков события "Потеря соединения"
  private LinkedList<ActionListener> failList = new LinkedList<ActionListener>();
 //---------------------Сервисные методы----------------------------
    private void initTimer(){
     ActionListener listener = new ActionListener(){
       public void actionPerformed(ActionEvent e) {
       e.setSource(address); //Заглушка удалённого сервера считается источником события
       try{
         object.ping();         
       }catch(RemoteException re){
         //Если сервер был подключен       
          System.out.println("Соединение потеряно");
          //Вызов обработчиков потери соединения
          Iterator iter = failList.iterator();
          while(iter.hasNext()){
            ActionListener action = (ActionListener)iter.next();
            action.actionPerformed(e);
          }
          stopPing();
         }
       }
     };

     if(timer != null) timer.stop();
     timer = new Timer(time, listener);
    }
  //-------------------------------------------------------- ----

  //--------------------Интерфейсные методы------------------------------------
  /**
   * Конструктор класса (в качестве времени дискретизации используется значение константы DEFAULT_TIME)
   * @param объект подлежащий пингованию
  */
  public PingService(INetworkRetryInterface object,NetworkAddress address){
    this(object,address, DEFAULT_TIME);
  }

  /**
   * Получить адрес пингуемого сервера 
   * @return адрес пингуемого сервера 
   */
  public NetworkAddress getAddress(){return address;}

  /**
   * Конструктор класса
   * @param object объект подлежащий пингованию
   * @param time период дискретизации пингования
   */
  public PingService(INetworkRetryInterface object, NetworkAddress address, int time){
   this.object = object;
   this.time = time;
   this.address = address; 
   initTimer();
  }

  /**
   * Полчить интервал пинга
   * @return интервал пинга
   */
  public int getDelay(){
   return time;
  }

  /**
   * Установит интервал пинга
   * @param delay - новый интервал пинга
   */
  public void setDelay(int delay){
   this.time = delay;
   initTimer();
  }


  /**
   * Начало пинга
   */
    public void startPing(){
        System.out.println("DEBUG: start ping PingService");
        initTimer();
        timer.start();
    }

   /**
    * Приостановить пинг
    */
    public void stopPing(){
        if(timer!=null) {
            timer.stop();
            System.out.println("DEBUG: stop ping PingService");
        }
    }

    /**
     * Добавить обработчик события "Потеря соединения"
     * @param listener - обработчик
     */
    public void addFailListener(ActionListener listener){
        failList.add(listener);
    }


    /**
     * Удалить все обработчики события "Потеря соединения"
     */
    public void removeAllFailListener(){failList.clear();}

    /**
    * Удалить все обработчики событий
    */
    public void removeAllListener(){removeAllFailListener();}

  //----------------------------------------------------------------------------

}
